package com.ksvip.next.components.util.event;

import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import com.google.common.eventbus.AsyncEventBus;
import com.ksvip.next.components.core.bean.Event;
import com.ksvip.next.components.core.bean.EventListener;

/**
 * 基于guava eventbus的调用工具类
 */
public class EventBusUtils {
    /**
     * 异步调用bean的methodName方法
     * 
     * @param bean
     * @param methodName
     * @param args
     */
    public static void invoke(Object bean, String methodName, Object[] args) {
        invoke(bean, methodName, args, null);
    }

    /**
     * 异步调用bean的methodName方法
     * 
     * @param bean
     * @param methodName
     * @param args
     * @param clazzs
     */
    public static void invoke(Object bean, String methodName, Object[] args, Class<?>[] clazzs) {
        // new一个事件
        Event event = new Event(bean, methodName, args, clazzs);
        // 将事件提交到bus上
        eventBus.post(event);
    }

    private static int                corePoolSize = Runtime.getRuntime().availableProcessors();
    /**
     * 多线程,使用固定线程池大小，非指定线程池大小可能大致OOM
     */
    private static ThreadPoolExecutor executor     = new ThreadPoolExecutor(corePoolSize, 30, 0L, TimeUnit.MILLISECONDS,
            new LinkedBlockingQueue<Runnable>(10000), new MyThreadFactory());
    /**
     * event bus
     */
    private static AsyncEventBus      eventBus     = new AsyncEventBus("default-enventBus", executor);
    /**
     * 事件监听器
     */
    private static EventListener      listener     = new EventListener();
    static {
        // 注册监听器到bus
        eventBus.register(listener);
        // 启动线程
        executor.prestartAllCoreThreads();
    }

    static class MyThreadFactory implements ThreadFactory {

        @Override
        public Thread newThread(Runnable r) {
            Thread thread = new Thread(r);
            thread.setName(Thread.currentThread().getName() + "-eventbus-common-thread");
            return thread;
        }

    }
}
